<?php

namespace app\api\middleware;


use app\api\biz\MenuBiz;
use app\api\biz\TokenBiz;
use app\common\Cache;
use app\common\enum\Cache as CacheEnum;
use app\common\enum\Code;
use app\common\Result;
use joncc\attribute\Attribute;
use think\facade\Config;
use think\Request;

class Auth
{

    public function handle(Request $request, \Closure $next)
    {
        [$module, $controller, $action] = get_mca();
        $className = 'app\\' . $module . '\controller\\' . $controller;

        $instance = Attribute::instance()->make($className);
        $authNeedless = $instance->authNeedless();
        if (!deny($action, $authNeedless)) {
            //免登录
            return $next($request);
        }

        $token = $request->header('token');
        if (empty($token)) {
            $token = input('token');
            if (empty($token)) {
                Result::httpExceptionByCode(Code::TokenNotFound);
            }
        }

        $sysSalt = Config::get('encrypt.sys_salt');
        if (empty($sysSalt)) {
            $sysSalt = 'jon-cc';
        }

        $agent = $request->header('user-agent');
        if (!empty($agent) && !str_contains($token, md5($agent . $sysSalt))) {
            Result::httpExceptionByCode(Code::TokenError);
        }

        Cache::set(CacheEnum::TOKEN, $token);
        $tokenBiz = TokenBiz::getUserId();
        if ($tokenBiz::hasError()) {
            Result::httpException(...$tokenBiz::getError());
        }

        $uid = $tokenBiz::getData();
        if (empty($uid)) {
            Result::httpExceptionByCode(Code::TokenError);
        }
        Cache::set(CacheEnum::UID, $uid);

        $permissionNeedless = $instance->permissionNeedless();
        if (in_array($uid, Config::get('admin.sys_user_id')) ||
            !deny($action, $permissionNeedless)) {
            //免鉴权
            return $next($request);
        }

        $menuBiz = MenuBiz::userList();
        if ($menuBiz::hasError()) {
            Result::httpException(...$menuBiz::getError());
        }

        $info = $menuBiz::getData();
        $userPermissionNeedless = $info['perms'];
        $tag = $controller . '.' . $action;
        if (deny($tag, $userPermissionNeedless)) {
            Result::httpExceptionByCode(Code::PermissionNeed);
        }

        return $next($request);
    }
}